/*
 * DatagramBuilder Library: serialize/deserialize data to/from datagram
 * Copyright (C) 2008 Rakov Ilya <RakovIlya@gmail.com>
 *
 * This library can be distributed under the terms of the GNU LGPLv2.
 * See the file COPYING.LIB.
 */


#ifndef DATAGRAM_BUILDER_H_
#define DATAGRAM_BUILDER_H_


/**
 * @file Builder.h

 * @brief Builder header file
 *
 * @date Nov 28, 2008
 * @author Rakov Ilya
 */


#include "Container.h"
#include "Parser.h"
#include "Tag.h"

#include <ostream>
#include <string>


/**
 * @brief This class provides an ability to serialize data.
 */
class Builder
{

public: // user interface

  typedef Container::cpointer_t cpointer_t;

  class ScopedTransaction;


  /**
   * @return Parser which can be used for data deserialization
   *
   */
  inline Parser GetParser() const;


  /**
   * @return Size of the already serialized data
   */
  inline size_t GetSize() const;


 /**
  * @brief Provides an ability to output the Builder's state into an output streams.
  * @param out Output stream
  */
  template< class CharType, class CharTrait >
  inline void ToStream( std::basic_ostream< CharType, CharTrait > &out ) const;


/**@{ @name Serialization interface */

  /**
   * @brief Common way to serialize data.
   *
   * @param value Data to serialize
   * @return The same builder
   * @note Provides exception-safety.
   */
  template < class T >
  inline Builder& operator <<( const T &value );


  /**
   * @brief Common way to serialize data.
   *
   * @param value Data to serialize
   * @return The same builder
   * @note Provides exception-safety.
   */
  template < class T >
  inline Builder& operator <<( T &value );


  /**
   * @brief Common way to serialize tagged data.
   *
   * @param value Data to serialize
   * @return The same builder
   * @note Provides exception-safety.
   */
  template < class T >
  inline Builder& operator <<( Tag< T > value );

/**@}*/


/**@{ @name Raw serialization interface */

  /**
   * @brief Serializes fixed-size values.
   *
   * The value appends to the end of the already contained data.
   * @param value Value
   */
  template< class T >
  inline void SerializeValue( const T value );


  /**
   * @brief Serialize variable data from memory range.
   *
   * The value appends to the end of the already contained data.
   *
   * SIZE_T is a data type of the variable data size.
   * @param bgn Pointer to the data begin
   * @param end Pointer to the data end
   * @exception serialization_error
   */
  template< class SIZE_T >
  inline void SerializeValue( cpointer_t bgn, cpointer_t end );

/**@}*/


private:  // implementation

  template< class T > friend class Mark;

  template< class T >
  inline void SerializeValue( const T value, size_t offset );


private:  // implementation

  Container container_;

};


/** @relates Builder
 *
 * @brief Provides an ability to output the Builder's state into an output streams.
 *
 * @param out Output stream
 * @param obj Builder
 */
template< class CharType, class CharTrait >
inline std::basic_ostream< CharType, CharTrait >&
operator <<( std::basic_ostream<CharType, CharTrait> &out, const Builder &obj );


#include "impl/BuilderImpl.h"


#endif /* DATAGRAM_BUILDER_H_ */
